﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
using System.Diagnostics;

namespace EgeUniversity.SolarCarProject
{
	public class ServerClass
	{
		//Events
		public event StatusChangedEventHandler ConnectionChanged;
		public event DataRecievedEventHandler DataRecieved;

		//Variables
		Socket socket { get; set; }
		TcpListener myListener { get; set; }
		Thread thread;
		string recievedData;

		~ServerClass()
		{
			//While destructing, kill thread
			if (thread != null && thread.IsAlive)
				thread.Abort();
		}

		public void Start()
		{//Multi-Thread to avoid deadlock
			thread = new Thread(new ThreadStart(StartThread));
			thread.Start();
		}

		void StartThread()
		{
			while (true)
			{
				try
				{
					//Start TPC listener
					IPAddress myIP = GetLocalIp();
					myListener = new TcpListener(myIP, 8001);
					myListener.Start();
					//myListener.LocalEndpoint;

					//Accept clients
					socket = myListener.AcceptSocket(); //Sync method
					OnConnectionChanged(ConnectionStatus.Connected);//Report status
					byte[] data = new byte[100];

					//Read data
					while (true)
					{
						int length = socket.Receive(data);
						recievedData = String.Empty;
						for (int i = 0; i < length; i++)
							recievedData += Convert.ToChar(data[i]).ToString();
						OnDataRecieved(recievedData);//Report data
					}
				}
				catch (SocketException)
				{
					OnConnectionChanged(ConnectionStatus.Disconnected);//Report status
				}
				catch (Exception e)
				{//If there is a problem
					//TODO: should be logged
					MessageBox.Show("Error : " + e.Message + "\n"+e.GetType().ToString());
				}
				finally
				{
					if (socket != null)
						socket.Close();
					if (myListener != null)
						myListener.Stop();
				}
			}
		}

		public virtual void OnConnectionChanged(ConnectionStatus e)
		{
			if (ConnectionChanged != null)
				ConnectionChanged(e);
		}

		public virtual void OnDataRecieved(string e)
		{
			if (DataRecieved != null)
				DataRecieved(e);
		}

		IPAddress GetLocalIp()
		{
			//Get this computer IP adress
			foreach (IPAddress ip in Dns.GetHostAddresses(Dns.GetHostName()))
				if (ip.AddressFamily == AddressFamily.InterNetwork)
					return ip;
			return null;
		}

		public void SetLocalIp()
		{
			//Process p = new Process();
			//p.StartInfo = new ProcessStartInfo(
			//    "netsh",
			//    "interface ip set address \"Wireless Network Connection\" static 192.168.1.10 255.255.255.0 192.168.1.254 1");
			//p.Start();
			//p.WaitForExit();
		}

		public void ResetLocalIp()
		{
			//Process.Start("netsh","interface ip set address \"Wireless Network Connection\" dhcp");
		}
	}

	public enum ConnectionStatus
	{
		Disconnected,
		Connected
	}

	public delegate void StatusChangedEventHandler(ConnectionStatus e);
	public delegate void DataRecievedEventHandler(string e);
}
